package com.aiserver.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;

/**
 * 图片验证码生成工具类
 */
public class CaptchaUtil {

    private static final Logger logger = LoggerFactory.getLogger(CaptchaUtil.class);

    // 验证码图片的宽度
    private static final int WIDTH = 120;
    // 验证码图片的高度
    private static final int HEIGHT = 40;
    // 验证码字符个数
    private static final int CODE_COUNT = 4;
    // 字体高度
    private static final int FONT_HEIGHT = 30;
    // 干扰线数量
    private static final int LINE_COUNT = 20;

    // 验证码字符集合
    private static final char[] CODE_SEQUENCE = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U',
            'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6',
            '7', '8', '9'
    };

    /**
     * 生成验证码图片
     * @param code 验证码字符串
     * @return base64编码的图片字符串
     */
    public static String generateCaptchaImage(String code) {
        try {
            // 创建图片缓冲区
            BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = buffImg.createGraphics();

            // 设置抗锯齿
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 创建随机数生成器
            Random random = new Random();

            // 设置背景色
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, WIDTH, HEIGHT);

            // 创建字体
            Font font = new Font("Arial", Font.BOLD, FONT_HEIGHT);
            g.setFont(font);

            // 绘制干扰线
            for (int i = 0; i < LINE_COUNT; i++) {
                int x1 = random.nextInt(WIDTH);
                int y1 = random.nextInt(HEIGHT);
                int x2 = random.nextInt(WIDTH);
                int y2 = random.nextInt(HEIGHT);
                g.setColor(getRandomColor(160, 200));
                g.drawLine(x1, y1, x2, y2);
            }

            // 绘制验证码字符
            for (int i = 0; i < code.length(); i++) {
                // 设置字体颜色
                g.setColor(getRandomColor(20, 130));
                
                // 计算字符位置
                int x = (WIDTH / CODE_COUNT) * i + 10;
                int y = HEIGHT - 10;
                
                // 随机旋转角度
                double angle = (random.nextDouble() - 0.5) * 0.4;
                g.rotate(angle, x, y);
                
                // 绘制字符
                g.drawString(String.valueOf(code.charAt(i)), x, y);
                
                // 恢复旋转
                g.rotate(-angle, x, y);
            }

            // 绘制干扰点
            for (int i = 0; i < 100; i++) {
                int x = random.nextInt(WIDTH);
                int y = random.nextInt(HEIGHT);
                g.setColor(getRandomColor(120, 180));
                g.fillOval(x, y, 1, 1);
            }

            g.dispose();

            // 将图片转换为base64字符串
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(buffImg, "png", baos);
            byte[] imageBytes = baos.toByteArray();
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            
            return "data:image/png;base64," + base64Image;

        } catch (IOException e) {
            logger.error("生成验证码图片失败", e);
            throw new RuntimeException("生成验证码图片失败", e);
        }
    }

    /**
     * 生成随机验证码字符串
     * @param length 验证码长度
     * @return 验证码字符串
     */
    public static String generateRandomCode(int length) {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        
        for (int i = 0; i < length; i++) {
            code.append(CODE_SEQUENCE[random.nextInt(CODE_SEQUENCE.length)]);
        }
        
        return code.toString();
    }

    /**
     * 生成随机颜色
     * @param min 最小值
     * @param max 最大值
     * @return 随机颜色
     */
    private static Color getRandomColor(int min, int max) {
        Random random = new Random();
        
        if (min > 255) min = 255;
        if (max > 255) max = 255;
        if (min < 0) min = 0;
        if (max < 0) max = 0;
        if (min > max) {
            int temp = min;
            min = max;
            max = temp;
        }
        
        int r = min + random.nextInt(max - min);
        int g = min + random.nextInt(max - min);
        int b = min + random.nextInt(max - min);
        
        return new Color(r, g, b);
    }
}